# coding=utf-8
from common.utils.types import Enum
from common.lottery import LOTTERY_TYPE
from common import orm

SSC_LOTTERY_TYPES = (
    LOTTERY_TYPE.CQ_SSC,
    LOTTERY_TYPE.XJ_SSC,
    LOTTERY_TYPE.TJ_SSC,
    LOTTERY_TYPE.FF_SSC,
)

SSC_BET_CATEGORY = Enum({
    'PLATE': (10L, u'两面盘'),
    'CHOSEN_ONE': (1L, u'定位胆'),
    'TWO': (2L, u'二星玩法'),
    'THREE_FRONT': (3L, u'前三玩法'),
    'THREE_MIDDLE': (4L, u'中三玩法'),
    'THREE_BACK': (5L, u'后三玩法'),
    'FOUR': (6L, u'四星玩法'),
    'FIVE': (7L, u'五星玩法'),
    # 'BSOE': (8L, u'大小单双'),
    'FUN': (9L, u'趣味玩法'),
})

# 三位数表示，第一位表示猜几位，第二位表示前(1), 中(2), 后(3), 特殊玩法(0)
# 第三位0(直选)， 1(单选), 2(组选)  3(组三),  6(组六),  5(和值)  9(特殊玩法)
BET_TYPE = Enum({
    "CHOSEN_ONE": (100L, u"定位胆"),

    "TWO_BACK_DIRECT": (230L, u"后二直选"),
    "TWO_BACK_GROUP": (232, u"后二组选复式"),
    "TWO_BACK_SUM": (235L, u"后二直选和值"),

    "THREE_FRONT_DIRECT": (310L, u'前三直选'),
    "THREE_FRONT_GROUP_THREE": (313L, u'前三组三'),
    "THREE_FRONT_GROUP_SIX": (316L, u'前三组六'),

    "THREE_MIDDLE_DIRECT": (320L, u"中三直选"),
    "THREE_MIDDLE_GROUP_THREE": (323L, u"中三组三"),
    "THREE_MIDDLE_GROUP_SIX": (326L, u"中三组六"),

    "THREE_BACK_DIRECT": (330, u"后三直选"),
    "THREE_BACK_GROUP_THREE": (333, u"后三组三"),
    "THREE_BACK_GROUP_SIX": (336, u"后三组六"),

    "FOUR_FRONT_DIRECT": (410L, u"前四直选"),
    "FOUR_BACK_DIRECT": (430L, u"后四直选"),

    "FIVE_DIRECT": (500L, u"五星直选"),
    "FIVE_ALL": (501L, u"五星通选"),

    "TWO_BSOE": (200L, u"大小单双"),

    "FUN_2": (209L, u"好事成双"),
    "FUN_3": (309L, u"三星报喜"),
    "FUN_4": (409L, u"四季发财"),

    # 以下玩法的编码不遵循上面三位数的规则
    "PLATE_SUM_BSOE": (600L, u"总和"),  # 两面盘总和的大小单双
    "PLATE_BOSE_1": (601L, u"万位"),  # 第一位数大小单双
    "PLATE_BOSE_2": (602L, u"千位"),
    "PLATE_BOSE_3": (603L, u"百位"),
    "PLATE_BOSE_4": (604L, u"十位"),
    "PLATE_BOSE_5": (605L, u"个位"),
    "PLATE_DRAGON_TIGER_1_5": (606L, u"龙虎和"),  # 万位和个位龙虎斗（龙虎斗就是比大小）

})

SSC_BET_CATEGORY_TYPE = [
    (SSC_BET_CATEGORY.CHOSEN_ONE, [BET_TYPE.CHOSEN_ONE]),
    (SSC_BET_CATEGORY.PLATE,
     [BET_TYPE.PLATE_SUM_BSOE, BET_TYPE.PLATE_BOSE_1, BET_TYPE.PLATE_BOSE_2, BET_TYPE.PLATE_BOSE_3,
      BET_TYPE.PLATE_BOSE_4, BET_TYPE.PLATE_BOSE_5,
      BET_TYPE.PLATE_DRAGON_TIGER_1_5]),
    (SSC_BET_CATEGORY.FIVE, [BET_TYPE.FIVE_DIRECT,
                             # BET_TYPE.FIVE_ALL
                             ]),
    (SSC_BET_CATEGORY.FOUR, [BET_TYPE.FOUR_FRONT_DIRECT, BET_TYPE.FOUR_BACK_DIRECT]),
    (SSC_BET_CATEGORY.THREE_FRONT, [BET_TYPE.THREE_FRONT_DIRECT, BET_TYPE.THREE_FRONT_GROUP_THREE,
                                    BET_TYPE.THREE_FRONT_GROUP_SIX]),
    (SSC_BET_CATEGORY.THREE_MIDDLE, [BET_TYPE.THREE_MIDDLE_DIRECT, BET_TYPE.THREE_MIDDLE_GROUP_THREE,
                                     BET_TYPE.THREE_MIDDLE_GROUP_SIX]),
    (SSC_BET_CATEGORY.THREE_BACK, [BET_TYPE.THREE_BACK_DIRECT, BET_TYPE.THREE_BACK_GROUP_THREE,
                                   BET_TYPE.THREE_BACK_GROUP_SIX]),
    (SSC_BET_CATEGORY.TWO, [BET_TYPE.TWO_BACK_DIRECT, BET_TYPE.TWO_BACK_GROUP, BET_TYPE.TWO_BACK_SUM]),

    # (SSC_BET_CATEGORY.BSOE, [BET_TYPE.TWO_BSOE]),
    (SSC_BET_CATEGORY.FUN, [BET_TYPE.FUN_2, BET_TYPE.FUN_3, BET_TYPE.FUN_4]),
]

BET_TYPE_DESC = {
    BET_TYPE.CHOSEN_ONE: u"每位至少选1个号码，与相同位置开奖号码一致即中<font color='#ff0000'>10%s</font>元",
    BET_TYPE.TWO_BACK_DIRECT: u"每位至少选1个号，按位猜对开奖号后2位即中<font color='#ff0000'>100%s</font>元",
    BET_TYPE.TWO_BACK_GROUP: u"至少选2个号，按位猜对开奖号后2位（顺序不限）即中<font color='#ff0000'>50%s</font>元",
    BET_TYPE.TWO_BACK_SUM: u"至少至少选1个和值，猜对开奖号后2位数字相加之和即中<font color='#ff0000'>100%s</font>元",
    BET_TYPE.THREE_FRONT_DIRECT: u"每位至少选1个号，按位猜对开奖号前3位即中<font color='#ff0000'>1000%s</font>元",
    BET_TYPE.THREE_FRONT_GROUP_THREE: u"至少选2个号，猜对开奖号前3位（顺序不限）即中<font color='#ff0000'>320%s</font>元",
    BET_TYPE.THREE_FRONT_GROUP_SIX: u"至少选3个号，猜对开奖号前3位（顺序不限）即中<font color='#ff0000'>160%s</font>元",
    BET_TYPE.THREE_BACK_DIRECT: u"每位至少选1个号，按位猜对开奖号后3位即中<font color='#ff0000'>1000%s</font>元",
    BET_TYPE.THREE_BACK_GROUP_THREE: u"至少选2个号，猜对开奖号后3位（顺序不限）即中<font color='#ff0000'>320%s</font>元",
    BET_TYPE.THREE_BACK_GROUP_SIX: u"至少选3个号，猜对开奖号后3位（顺序不限）即中<font color='#ff0000'>160%s</font>元",
    BET_TYPE.THREE_MIDDLE_DIRECT: u"每位至少选1个号，按位猜对开奖号中间3位即中<font color='#ff0000'>1000%s</font>元",
    BET_TYPE.THREE_MIDDLE_GROUP_THREE: u"至少选2个号，猜对开奖号中间3位（顺序不限）即中<font color='#ff0000'>320%s</font>元",
    BET_TYPE.THREE_MIDDLE_GROUP_SIX: u"至少选3个号，猜对开奖号中间3位（顺序不限）即中<font color='#ff0000'>160%s</font>元",
    BET_TYPE.FOUR_FRONT_DIRECT: u"每位至少选1个号，按位猜对开奖号即中<font color='#ff0000'>10000%s</font>元",
    BET_TYPE.FOUR_BACK_DIRECT: u"每位至少选1个号，按位猜对开奖号即中<font color='#ff0000'>10000%s</font>元",
    BET_TYPE.FIVE_DIRECT: u"每位至少选1个号，按位猜对开奖号即中<font color='#ff0000'>100000%s</font>元",
    BET_TYPE.FIVE_ALL: u"每位至少选1个号，按位猜对开奖号，最高中<font color='#ff0000'>20440%s</font>元",
    BET_TYPE.TWO_BSOE: u"至少选2个号，猜对开奖后2位的大(&gt;=5)、小(&lt;5)、单、双，即中<font color='#ff0000'>4%s</font>元",
    BET_TYPE.FUN_2: u"至少选1个号码，只要所选号码在开奖号码中出现2次，即中<font color='#ff0000'>10%s</font>元",
    BET_TYPE.FUN_3: u"至少选1个号码，只要所选号码在开奖号码中出现3次，即中<font color='#ff0000'>120%s</font>元",
    BET_TYPE.FUN_4: u"至少选1个号码，只要所选号码在开奖号码中出现4次，即中<font color='#ff0000'>2000%s</font>元"
}

BET_TYPE_DESC_V3 = {
    BET_TYPE.CHOSEN_ONE: u"每位至少选1个号码，与相同位置开奖号码一致",
    BET_TYPE.TWO_BACK_DIRECT: u"每位至少选1个号，按位猜对开奖号后2位",
    BET_TYPE.TWO_BACK_GROUP: u"至少选2个号，按位猜对开奖号后2位（顺序不限）",
    BET_TYPE.TWO_BACK_SUM: u"至少至少选1个和值，猜对开奖号后2位数字相加之和",
    BET_TYPE.THREE_FRONT_DIRECT: u"每位至少选1个号，按位猜对开奖号前3位",
    BET_TYPE.THREE_FRONT_GROUP_THREE: u"至少选2个号，猜对开奖号前3位（顺序不限）",
    BET_TYPE.THREE_FRONT_GROUP_SIX: u"至少选3个号，猜对开奖号前3位（顺序不限）",
    BET_TYPE.THREE_BACK_DIRECT: u"每位至少选1个号，按位猜对开奖号后3位",
    BET_TYPE.THREE_BACK_GROUP_THREE: u"至少选2个号，猜对开奖号后3位（顺序不限）",
    BET_TYPE.THREE_BACK_GROUP_SIX: u"至少选3个号，猜对开奖号后3位（顺序不限）",
    BET_TYPE.THREE_MIDDLE_DIRECT: u"每位至少选1个号，按位猜对开奖号中间3位",
    BET_TYPE.THREE_MIDDLE_GROUP_THREE: u"至少选2个号，猜对开奖号中间3位（顺序不限）",
    BET_TYPE.THREE_MIDDLE_GROUP_SIX: u"至少选3个号，猜对开奖号中间3位（顺序不限）",
    BET_TYPE.FOUR_FRONT_DIRECT: u"每位至少选1个号，按位猜对开奖号",
    BET_TYPE.FOUR_BACK_DIRECT: u"每位至少选1个号，按位猜对开奖号",
    BET_TYPE.FIVE_DIRECT: u"每位至少选1个号，按位猜对开奖号",
    BET_TYPE.FIVE_ALL: u"每位至少选1个号，按位猜对开奖号",
    BET_TYPE.TWO_BSOE: u"至少选2个号，猜对开奖后2位的大(>=5)、小(<5)、单、双",
    BET_TYPE.FUN_2: u"至少选1个号码，只要所选号码在开奖号码中出现2次",
    BET_TYPE.FUN_3: u"至少选1个号码，只要所选号码在开奖号码中出现3次",
    BET_TYPE.FUN_4: u"至少选1个号码，只要所选号码在开奖号码中出现4次",

    BET_TYPE.PLATE_SUM_BSOE: u"大于等于23为大；小于等于22为小；单数为单，双数为双",
    BET_TYPE.PLATE_BOSE_1: u"5-9为大；0-4为小；13579为单，02468为双",
    BET_TYPE.PLATE_BOSE_2: u"5-9为大；0-4为小；13579为单，02468为双",
    BET_TYPE.PLATE_BOSE_3: u"5-9为大；0-4为小；13579为单，02468为双",
    BET_TYPE.PLATE_BOSE_4: u"5-9为大；0-4为小；13579为单，02468为双",
    BET_TYPE.PLATE_BOSE_5: u"5-9为大；0-4为小；13579为单，02468为双",
    BET_TYPE.PLATE_DRAGON_TIGER_1_5: u"万位大于个位为龙，万位小于个位为虎，万位等于个位为和",

}


def get_avaliable_bet_types():
    _list = []
    for category, bet_types in SSC_BET_CATEGORY_TYPE:
        type_list = []
        _id = 1
        for bet_type in bet_types:
            type_list.append({
                'id': _id,
                'title': BET_TYPE.get_label(bet_type),
                'play_id': bet_type,
                'des': BET_TYPE_DESC[bet_type],
                'rule': '',
                'support': 1
            })
            _id += 1
        data = {
            'id': category,
            'title': SSC_BET_CATEGORY.get_label(category),
            'support': 1,
            'list': type_list
        }
        _list.append(data)
    return _list


def get_avaliable_bet_types_v3(cvc=1):
    _list = []

    for category, bet_types in SSC_BET_CATEGORY_TYPE:
        if cvc < 23 and category == SSC_BET_CATEGORY.PLATE:
            continue

        type_list = []
        _id = 1
        for bet_type in bet_types:
            type_list.append({
                'id': _id,
                'title': BET_TYPE.get_label(bet_type),
                'play_id': bet_type,
                'des': BET_TYPE_DESC_V3[bet_type],
                'rule': '',
                'support': 1
            })
            _id += 1
        data = {
            'id': category,
            'title': SSC_BET_CATEGORY.get_label(category),
            'support': 1,
            'list': type_list
        }
        _list.append(data)
    return _list


class SSCActivity(object):
    id = orm.Column(orm.Integer, primary_key=True)
    term = orm.Column(orm.VARCHAR)  # 期号
    number = orm.Column(orm.VARCHAR)  # 开奖结果
    reference = orm.Column(orm.TEXT)  # 爬取结果页url
    status = orm.Column(orm.SmallInteger)  # 状态
    start_ts = orm.Column(orm.Integer)  # 我方开始时间戳（整点）
    end_ts = orm.Column(orm.Integer)  # 我方结束时间戳（略早于官方）
    announce_ts = orm.Column(orm.Integer)  # 爬取到结果的时间戳
    created_at = orm.Column(orm.DATETIME)
    updated_at = orm.Column(orm.DATETIME)


class SSCTrend(object):
    ''' 五星基本走势，每位（个十百千万）各占一个字段，类型是字符串，
            格式是用逗号分隔的遗漏次数。如果当期出现，遗漏次数为0. 由于
            这玩意儿理论上可以无限前溯，所以最开始的几期里面会出现`x`，表示
            遗漏次数未知。后续其他走势图的部分数据可以直接从这里拿。统计数据不做存储，
            考虑使用redis进行cache，或者让客户端自己算。

            NOTE: 由于爬虫的结果是乱序的，不能保证开奖的顺序是递增的。这里在插入数据的时候，
            要考虑到这个问题。
    '''
    id = orm.Column(orm.Integer, primary_key=True)
    term = orm.Column(orm.VARCHAR)
    number = orm.Column(orm.VARCHAR)
    idx_0 = orm.Column(orm.VARCHAR)  # 万位
    idx_1 = orm.Column(orm.VARCHAR)  # 千位
    idx_2 = orm.Column(orm.VARCHAR)  # 百位
    idx_3 = orm.Column(orm.VARCHAR)  # 十位
    idx_4 = orm.Column(orm.VARCHAR)  # 个位
    # 一星单选到五星单选可以直接用前面的，还有些组合所需数据重复
    miss_5 = orm.Column(orm.TEXT)  # 二星组选
    miss_6 = orm.Column(orm.TEXT)  # 组三单选
    miss_10 = orm.Column(orm.TEXT)  # 大小单双
    miss_11 = orm.Column(orm.TEXT)  # 二星组选和值
    # 新的统一的玩法遗漏
    miss_232 = orm.Column(orm.TEXT)
    miss_235 = orm.Column(orm.TEXT)
    miss_313 = orm.Column(orm.TEXT)
    miss_316 = orm.Column(orm.TEXT)
    miss_323 = orm.Column(orm.TEXT)
    miss_326 = orm.Column(orm.TEXT)
    miss_333 = orm.Column(orm.TEXT)
    miss_336 = orm.Column(orm.TEXT)
    miss_200 = orm.Column(orm.TEXT)
    miss_209 = orm.Column(orm.TEXT)
    miss_309 = orm.Column(orm.TEXT)
    miss_409 = orm.Column(orm.TEXT)

    @classmethod
    def get_defaults(cls):
        data = {}
        for k in range(10):
            data['idx_%s' % k] = ','.join('x' * 10)
        data['miss_5'] = data['miss_6'] = ','.join('x' * 10)
        data['miss_10'] = '|'.join([','.join('x' * 4)] * 2)
        data['miss_11'] = ','.join('x' * 19)

        data['miss_232'] = ','.join('x' * 10)
        data['miss_235'] = ','.join('x' * 19)
        data['miss_313'] = ','.join('x' * 10)
        data['miss_316'] = ','.join('x' * 10)
        data['miss_323'] = ','.join('x' * 10)
        data['miss_326'] = ','.join('x' * 10)
        data['miss_333'] = ','.join('x' * 10)
        data['miss_336'] = ','.join('x' * 10)
        data['miss_200'] = '|'.join([','.join('x' * 4)] * 2)
        data['miss_209'] = ','.join('x' * 10)
        data['miss_309'] = ','.join('x' * 10)
        data['miss_409'] = ','.join('x' * 10)

        return data

    def get_stat(self, bet_type):
        ''' 根据玩法返回统计（遗漏、冷热、最大和上次）数据
            这个数据应该被缓存起来（因为冷热和最大需要实时计算）
            对于每一期而言，这个数据是固定的
        '''
        resp = {}
        _config = {
            BET_TYPE.TWO_BACK_DIRECT: (3, 5),
            BET_TYPE.THREE_FRONT_DIRECT: (0, 3),
            BET_TYPE.THREE_MIDDLE_DIRECT: (1, 3),
            BET_TYPE.THREE_BACK_DIRECT: (2, 5),
            BET_TYPE.FOUR_FRONT_DIRECT: (0, 4),
            BET_TYPE.FOUR_BACK_DIRECT: (1, 5),
            BET_TYPE.FIVE_DIRECT: (0, 5),
            BET_TYPE.FIVE_ALL: (0, 5)
        }
        if bet_type == BET_TYPE.CHOSEN_ONE:
            resp['miss'] = '|'.join([self.idx_0, self.idx_1, self.idx_2,
                                     self.idx_3, self.idx_4])

        elif bet_type in _config.keys():
            for k, v in _config.iteritems():
                if bet_type == k:
                    result = []
                    for k in range(v[0], v[1]):
                        result.append(getattr(self, 'idx_%s' % k))
                    resp['miss'] = '|'.join(result)

        elif 1 <= bet_type <= 3:
            result = []
            for k in xrange(1, bet_type + 1):
                result.append(getattr(self, 'idx_%s' % (5 - k)))
            resp['miss'] = '|'.join(reversed(result))
        elif bet_type == 13:
            resp['miss'] = '|'.join([self.idx_1, self.idx_2,
                                     self.idx_3, self.idx_4])
        elif bet_type in (5, 6, 10, 11):
            resp['miss'] = getattr(self, 'miss_%s' % bet_type)
        elif bet_type in (7, 8):
            resp['miss'] = self.miss_6
        elif bet_type in (4, 9, 12):
            resp['miss'] = '|'.join([
                self.idx_0, self.idx_1, self.idx_2, self.idx_3,
                self.idx_4])
        else:
            k = 'miss_%s' % bet_type
            resp['miss'] = getattr(self, k)
        return resp
